/* 
   Copyright(C)2012 Fredy Ramirez - www.pacificcoolwave.com
 
   This file is part of the TerraCool project.
	
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;

namespace Pcw.TerraCool
{
	internal sealed class CatalogValues
	{
		Dictionary<string,CatalogData> data = new Dictionary<string, CatalogData>();

		internal CatalogValues ()
		{
		}

		internal void AddStringsTranslated (XmlNode xNode)
		{
			string id, id_plural, msg, msg_plural = null;
			string name, text = null;

			foreach(XmlNode str in xNode.ChildNodes)
			{
				if (str.NodeType != XmlNodeType.Element)
					continue;

				name = str.Name;

				if (name != "String")
					continue;

				id = id_plural = msg = msg_plural = null;				

				foreach(XmlAttribute xAttr in str.Attributes)
				{
					text = xAttr.Value;
					switch (xAttr.Name)
					{
						case "id":
							id = UnEscape(text);
							break;
						case "id_plural":
							id_plural = UnEscape(text);
							break;
						case "msg":
							msg = UnEscape(text);
							break;
						case "msg_plural":
							msg_plural = UnEscape(text);
							break;
					}
				}

				if (id == null)
					continue;

				if (data.ContainsKey(id)) {
					data[id].Msg = msg;
					data[id].IdPlural = id_plural;
					data[id].MsgPlural = msg_plural;
				}
				else {
					data.Add(id, new CatalogData(msg, id_plural, msg_plural));
				}
			}

			//foreach(KeyValuePair<string, CatalogData> pair in data)
			//	Console.WriteLine(" Data id: {0} - Msg: {1}", pair.Key, data[pair.Key].Msg);
			
		}

		internal string GetSingle(string id) 
		{
			if (data.Count < 1)
				return id;

			string idLiteral = null;
			if (!data.ContainsKey(id)) {
				idLiteral = EscapeUnicode(id);
				if (!data.ContainsKey(idLiteral))
					return id;
			}

			if (idLiteral == null)
				idLiteral = id;

			if (String.IsNullOrEmpty(data[idLiteral].Msg))
				return id;

			return data[idLiteral].Msg;
		}

		internal string GetPlural(string id, string pluralId) 
		{
			if (data.Count < 1)
				return pluralId;

			string idLiteral = null;
			if (!data.ContainsKey(id)) {
				idLiteral = EscapeUnicode(id);
				if (!data.ContainsKey(idLiteral))
					return pluralId;
			}

			if (idLiteral == null)
				idLiteral = id;

			if (String.IsNullOrEmpty(data[idLiteral].MsgPlural))
				return pluralId;

			if (pluralId != data[idLiteral].IdPlural)
				return pluralId;

			return data[idLiteral].MsgPlural;
		}

		public static string UnEscape(string input)
		{
			string result = input;
			result = result.Replace(@"\\", "\\"); 
			result = result.Replace(@"\""", "\"");
			result = result.Replace(@"\a", "\a");
			result = result.Replace(@"\b", "\b");
			result = result.Replace(@"\f", "\f");
			result = result.Replace(@"\n", "\n");
			result = result.Replace(@"\r", "\r");
			result = result.Replace(@"\t", "\t");
			result = result.Replace(@"\v", "\v");
			result = result.Replace(@"\0", "\0");
			//Console.WriteLine("UnEscape result: {0}", result);
			return result;
		}

		public static string EscapeUnicode(string input)
		{

			string result = input;
			result = result.Replace("\\", @"\\"); 
			result = result.Replace("\"", @"\""");
			result = result.Replace("\a", @"\a");
			result = result.Replace("\b", @"\b");
			result = result.Replace("\f", @"\f");
			result = result.Replace("\n", @"\n");
			result = result.Replace("\r", @"\r");
			result = result.Replace("\t", @"\t");
			result = result.Replace("\v", @"\v");
			result = result.Replace("\0", @"\0");

			StringBuilder builder = new StringBuilder();

			for (int i = 0; i < result.Length; i++)
			{
				if (char.IsSurrogatePair(result, i)) {
					builder.Append("\\U" + char.ConvertToUtf32(result, i).ToString("X8"));
					i++;  //skip the next char    
				}
				else
				{
					int charVal = char.ConvertToUtf32(result, i);
					if (charVal > 127) {
						builder.Append("\\u" + charVal.ToString("X4"));
					}
					else {
						//an ASCII character
						builder.Append(result[i]);
					}
				}
			}

			result = builder.ToString();
			return result;
		}
	}
}


